#include <iostream>
#include <string>
#include <vector>
#include <sw/redis++/redis++.h>
#include "../util.hpp"

// get 和 set 使用 
void test1(sw::redis::Redis &redis){
    std::cout << "Get 和 Set 使用" << std::endl;
    // 使用前先清空数据库, 避免之前残留数据产生干扰
    redis.flushall();

    // 使用 set 命令设置键值对
    redis.set("key1", "value1");

    // 使用 get 命令获取键的值
    auto value1 = redis.get("key1"); // 这里返回的OptionalString可以表示一个非法值
    // optional 可以隐式转换成 bool 类型
    if (value1) {
        std::cout << "key1: " << *value1 << std::endl; // 输出: key1: value2
    } else {
        std::cout << "key1 not found" << std::endl;
    }
    auto value2 = redis.get("key2"); // key2 不存在
    std::cout << "key2: " << value2.value() << std::endl; // 输出: key2: <nil>, 这里就不能用指针来输出了, 最好用 value() 方法 

    redis.set("key2", "value2");
}

void test2(sw::redis::Redis &redis){
    std::cout << "Exists 和 Del 使用" << std::endl;
    redis.flushall();
    
    redis.set("key", "value1");
    auto ret = redis.exists("key");
    std::cout << "key exists: " << ret << std::endl; // 输出: key exists: 1
    // 多级判断 redis.exists({"key1", "key2", "key3"}) 返回一个 值 表示几个 key 存在
    ret = redis.exists({"key", "key2", "key3"});
    std::cout << "key, key2, key3 exists: " << ret << std::endl; // 输出: key, key2, key3 exists: 1

    redis.del("key");
    ret = redis.exists("key");
    std::cout << "key exists after delete: " << ret << std::endl; // 输出: key exists after delete: 0
}

void test3(sw::redis::Redis &redis){
    std::cout << "Keys 使用" << std::endl;
    redis.flushall();

    redis.set("key1", "value1");
    redis.set("key2", "value2");
    redis.set("key3", "value3");

    // 获取所有的键 
    // keys 的第二个参数, 是一个插入迭代器, 需准备好一个保存结果的容器
    // 接下来再创建一个插入迭代器指向容器的位置, 把 keys 的结果插入到容器中
    std::vector<std::string> ret;
    auto it = std::back_insert_iterator(ret);
    redis.keys("*", it); // 匹配所有键
    for (const auto& key : ret) {
        std::cout << "Key: " << key << std::endl;
    }
}

void test4(sw::redis::Redis &redis){
    using namespace std::chrono_literals; // 使用 chrono 的字面量
    std::cout << "Expire 和 TTL" << std::endl;
    redis.flushall();

    redis.set("key1", "value1");
    redis.expire("key1", std::chrono::seconds(5)); // 设置 key1 的过期时间为 5 秒
    std::this_thread::sleep_for(std::chrono::seconds(3s)); // 等待 3 秒
    long long time = redis.ttl("key1"); // 获取 key1 的剩余过期时间    
    if (time) {
        std::cout << "TTL for key1: " << time << " seconds" << std::endl;
    } else {
        std::cout << "key1 does not have a TTL" << std::endl;
    }
}

void test5(sw::redis::Redis &redis){
    std::cout << "Type" << std::endl;
    redis.flushall();

    redis.set("key1", "1111");
    std::string res = redis.type("key1"); 
    std::cout << "Type of key1: " << res << std::endl; 

    redis.hset("hash1", "field1", "value1");
    res = redis.type("hash1");
    std::cout << "Type of hash1: " << res << std::endl; // 输出: Type of hash1: hash
}

int main(){
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    // 如果 Redis 设置了密码，请在这里添加认证
    redis.auth("123456");  // 替换为你的 Redis 密码
    test5(redis);

    return 0;
}